package com.publicprintingwithjason.gui;




import com.golden.gamedev.Game;
import com.golden.gamedev.object.Background;
import com.golden.gamedev.object.GameFont;
import com.golden.gamedev.object.PlayField;
import com.golden.gamedev.object.background.ImageBackground;
import com.sun.org.apache.bcel.internal.generic.INSTANCEOF;

import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author azul
 */
public class GuiControl extends Game{
    private BufferedImage[] biImpressora;
    private BufferedImage biUser;
    private Background background;
    private PlayField pf;
    private Waypoints wp;
    private Printer[] printers;
    private User[] users;
    private User supplyMan;
    private Random rnd;

    // Cores utilizadas para representar os estados da impressora
    // Verde: Funcional
    // Amarelo: Imprimindo
    // Vermelho: Sem suprimentos
    public final int green = 0;
    public final int yellow = 1;
    public final int red = 2;

    private final double speed = 0.1;
    
    // Metodo utilizado pelo GTGE
    public void initResources() {
        // Waypoints utilizados para locomover os usuarios
        wp = Waypoints.getWP();
        rnd = new Random();

        // Imagens
        biImpressora = new BufferedImage[3];
        biImpressora[0] = getImage("resources/impressoraVerde.gif");
        biImpressora[1] = getImage("resources/impressoraAmar.gif");
        biImpressora[2] = getImage("resources/impressoraVerm.gif");
        biUser = getImage("resources/user.gif");
        background = new ImageBackground(getImage("resources/bg.gif"));

        // Playfield
        pf = new PlayField();
        pf.setBackground(background);

        // Cria o vetor de impressoras e o vetor de agentes
        addPrinters();
        addUsers();
        // Cria o responsavel pelos suprimentos
        supplyMan = new User(wp.getWpSuplyMan()[0].x, wp.getWpSuplyMan()[0].y);
        supplyMan.setImage(getImage("resources/suplyMan.gif"));
        pf.add(supplyMan);    
    }

    // Metodo utilizado pelo GTGE
    public void update(long elapsedTime) {
        // updating the game variables
        pf.update(elapsedTime);
        for(int i=0; i < users.length; i++){
            if(!users[i].hasDestination()){
            	users[i].setSpeed(0, 0);
            }
            else{
            	setMovement(users[i]);
            }
        }
        if(supplyMan.hasDestination()){
            setMovement(supplyMan);
        }
    }

    // Metodo utilizado pelo GTGE
    public void render(Graphics2D g) {
        // rendering to the screen
        pf.render(g);
    }

    // Gera o vetor de usuarios
    private void addUsers() {
    	users = new User[3];
    	for(int i=0; i < 3; i++){
    		users[i] = new User(wp.getWayPoints()[rnd.nextInt(wp.getWayPoints().length)][rnd.nextInt(wp.getWayPoints()[0].length)]);
    		users[i].setImage(biUser);
            pf.add(users[i]);
        }    	
    }

    // Gera o vetor de impressoras
    private void addPrinters() {
    	printers = new Printer[wp.getWpPrinters().length];
    	for(int i=0; i < wp.getWpPrinters().length; i++){
            printers[i] = new Printer(wp.getWpPrinters()[i][0]);
            printers[i].setImages(biImpressora);
            pf.add(printers[i]);
        }    	
    }

    // Utilizado para atualizar movimento dos sprites
    private void setMovement(User user) {
        if(user.getNextDestination().x == user.getPosition().x && user.getNextDestination().y == user.getPosition().y){
            Point destination = user.removeDestination();
            user.setSpeed(0, 0);
            user.setLocation(destination.x, destination.y);
        }
        else{
            if(user.getNextDestination().x > user.getPosition().x){
                user.setHorizontalSpeed(speed);
            }
            else if(user.getNextDestination().x < user.getPosition().x){
                user.setHorizontalSpeed(-speed);
            }
            else if(user.getNextDestination().y < user.getPosition().y){
                user.setVerticalSpeed(-speed);
            }
            else if(user.getNextDestination().y > user.getPosition().y){
                user.setVerticalSpeed(speed);
            }
        }
    }
    
    // ############################## Metodos chamados no Jason #########################################
    /**
     * Gera um caminho aleatorio para um determinado usuario
     * @param userIndex Indice do usuario
     */
    public void randomWalk(int userIndex) {
    	users[userIndex].addDestination(wp.getPath(users[userIndex].getPosition(),
                          			wp.getWayPoints()[rnd.nextInt(wp.getWayPoints().length)][rnd.nextInt(wp.getWayPoints()[0].length)]));
    }
    
    /**
     * Move o iesimo usuario ate a iesima impressora
     * @param userIndex Indice do usuario
     * @param printerIndex Indice da impressora
     */
    public void moveToPrinter(int userIndex, int printerIndex){
        users[userIndex].addDestination(wp.getPath(users[userIndex].getPosition(), wp.getWpPrinters()[printerIndex][1]));
    }

    /**
     * Envia o encarregado dos duprimentos para uma determinada impressora
     * @param printerIndex Indice da impressora desejada
     */
    public void sendSuplyManToPrinter(int printerIndex){
    	ArrayList<Point> path = new ArrayList<Point>();
    	// Se estiver no escritorio ou se a última posicao da lista for o escrtiorio, utiliza os wps para chegar em uma esquina
        if((supplyMan.getPosition().x == wp.getWpSuplyMan()[0].x && supplyMan.getPosition().y == wp.getWpSuplyMan()[0].y) ||
           (supplyMan.getLastDestination() != null && supplyMan.getLastDestination().x == wp.getWpSuplyMan()[0].x && supplyMan.getLastDestination().y == wp.getWpSuplyMan()[0].y)){
//    	if((supplyMan.getPosition().x == wp.getWpSuplyMan()[0].x && supplyMan.getPosition().y == wp.getWpSuplyMan()[0].y)){
            path.addAll(Arrays.asList(wp.getWpSuplyMan()));
            path.addAll(wp.getPath(wp.getWpSuplyMan()[2], wp.getWpPrinters()[printerIndex][1]));
        }
        else{
        	if(supplyMan.hasDestination()){
        		path.addAll(wp.getPath(supplyMan.getLastDestination(), wp.getWpPrinters()[printerIndex][1]));
        	}
        	else{
        		path.addAll(wp.getPath(supplyMan.getPosition(), wp.getWpPrinters()[printerIndex][1]));
        	}
        }
        supplyMan.addDestination(path);
    }

    /**
     * Envia o responsavel pelos suprimentos para seu QG
     */
    public void sendSuplyManHome(){
        ArrayList<Point> path = new ArrayList<Point>();
        path.addAll(wp.getPath(supplyMan.getPosition(), wp.getWpSuplyMan()[2]));
        path.add(wp.getWpSuplyMan()[1]);
        path.add(wp.getWpSuplyMan()[0]);
        supplyMan.addDestination(path);
    }

    /**
     * Troca a cor de uma impressora i. As cores sÃ£o definidas pelas variaveis
     * green, yellow e red
     * @param printerIndex Indice da impressora
     * @param color Cor atribuÃ­da
     */
    public void chancePrinterColor(int printerIndex, int color){
        printers[printerIndex].setFrame(color);
    }
    
    // Retorna a lista de usuarios
    public User[] getUsers() {
        return users;
    }
    
    // Retorna a lista de impressoras
    public Printer[] getPrinters() {
        return printers;
    }
    
    // Retorna o supplier
    public User getSupplier() {
        return supplyMan;
    }

    //posicao da entrada impressora
    public Point getPrinterEntrancePosition(int printerIndex) {
    	return wp.getWpPrinters()[printerIndex][1];
    }
    
    //posicao home do supplier
    public Point getSupplierHomePosition() {
    	return wp.getWpSuplyMan()[0];
    }
}
